博客简单支持PWA
撰写时间: 2019-11-01 总共: 3224 字 转载请注明: BY-SA 4.0(除特别声明或转载文章外)
PWA
PWA(Progressive Web App) 渐进式增强Web应用。
目的将网页应用可以和原生应用一样给用户原生app的使用体验。
当然更多的可以查看相关文档。
为了配合我的github pages 上的博客
主要是利用缓存API进行响应的存储和拦截请求从缓存返回响应。
在断网状态下也可以返回一个自定义的断网页面。
主要的技术是利用:
Web App Manifest
Service Workers
Promise
Cache API
结合上面3个就能简单实现PWA的web app 的简单支持了。
参考文档链接:
解决问题和方法
无法离线使用:
使用缓存和Service Workers
等技术实现离线加载缓存内容
无法添加到桌面:
通过使用manifest.json
文件配置,可以将web app 添加到主屏幕。
开始
使用sw.js
// 应用前缀
const APP_PREFIX = 'XTRUET';
// 根据每次的sw.js的版本更改缓存内容
// 需要更改缓存的时候需要改变这个版本才能进行重新安装状态
const VERSION = 'v_3.0.1';
// 缓存的名称
const CACHE_NAME = APP_PREFIX + VERSION;
// 需要缓存的url静态资源
const URLS = [
'/index.html',
'/public/css/style.css',
'/public/js/toc.js',
'/public/js/prism.js',
'/public/image/alipay.png',
'/public/image/wechatpay.png',
'/public/image/404.jpg',
'/public/simple-jekyll-search/search.json',
'https://ae01.alicdn.com/kf/Hb70dbc4687de416199bb2b295704957f0.png'
]
// 缓存资源
self.addEventListener('install',(e)=>{
// 等待promise完成标记安装状态为完成安装
e.waitUntil(
// 打开一个缓存对象
caches.open(CACHE_NAME).then((cache)=>{
console.log(`install:${CACHE_NAME}`);
// 以url为key,内容为value
return cache.addAll(URLS);
}).then(()=>self.skipWaiting())
);
});
// 拦截请求
this.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function() {
return fetch(event.request.url).then(function(response) {
return caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request.url, response.clone());
return response;
});
});
}).catch(function() {
return caches.match('/public/image/404.jpg');
})
);
});
// 移除旧缓存
self.addEventListener('activate',(e)=>{
e.waitUntil(
caches.keys().then((keys)=>{
var cacheWhitelist = keys.filter((key)=>key.indexOf(APP_PREFIX));
cacheWhitelist.push(CACHE_NAME);
return Promise.all(keys.map((key,i)=>{
if(cacheWhitelist.indexOf(key) === -1){
console.log(`delete cache:${keys[i]}`);
return caches.delete(keys[i]);
}
}));
}).then(()=>clients.claim())// 更新客户端
);
})
建立manifest.json
{
"short_name": "XTRUET",
"name": "XTRUET",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "/",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
short_name: 应用展示的名称(桌面上显示的名称)
icons: 定义不同尺寸的应用图标
start_url: 定义桌面启动的 URL
description: 应用描述,可以参考 meta 中的 description
display: 定义应用的显示方式,有 4 种显示方式,分别为:
fullscreen: 全屏
standalone: 应用
minimal-ui: 类似于应用模式,但比应用模式多一些系统导航控制元素,但又不同于浏览器模式
browser: 浏览器模式,默认值
name: 应用名称(浏览器提示用户添加和Android启动屏显示的名称)
orientation: 定义默认应用显示方向,竖屏、横屏
prefer_related_applications: 是否设置对应移动应用,默认为 false
related_applications: 获取移动应用的方式
background_color: 应用加载之前的背景色,用于应用启动时的过渡
theme_color: 定义应用默认的主题色
dir: 文字方向,3 个值可选 ltr(left-to-right), rtl(right-to-left) 和 auto(浏览器判断),默认为 auto
lang: 语言
scope: 定义应用模式下的路径范围,超出范围会已浏览器方式显示
在页面添加
<link rel="manifest" href="/manifest.json">
注册使用sw.js
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js',
{ scope: '/' }).then(function(reg) {
if(reg.installing) {
console.log('Service worker installing');
} else if(reg.waiting) {
console.log('Service worker installed');
} else if(reg.active) {
console.log('Service worker active');
}
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
</script>
上述两个需要写在页面的内容,我将他们放置到了我的_include
文件加的head.html
好处
部分浏览器支持添加到电脑桌面快捷方式,将应用成为一个类桌面的应用。
使用缓存提高加载速度,提升用户体验。
问题
浏览器兼容不好,蛮多浏览器没有主动能提示用户这是个pwa应用。
即使我们使用谷歌浏览器添加到了主屏幕,也可以不出现,有些手机系统桌面直接就是一级菜单,不存在能添加快捷方式的地方,所以还是跟没有一样。。。